#include "strokecommand.h"
#include "../core.h"
#include "../geom/geom.h"
#include "../om/curve.h"
#include "../om/objectmanager.h"

namespace ShCo
{

class StrokeCommandImpl : public Impl<StrokeCommand>
{
public:
    void init();
    void exit();
    void draw();
    SsPoint* _ctrlPnt1;
    SsPoint* _ctrlPnt2;
    Curve* _curve;
};

void StrokeCommandImpl::init()
{
    _ctrlPnt1 = SH_NULL;
    _ctrlPnt2 = SH_NULL;
    _curve = SH_NULL;
}

void StrokeCommandImpl::exit()
{
    SH_SAFE_DELETE(_ctrlPnt1);
    SH_SAFE_DELETE(_ctrlPnt2);
    SH_SAFE_DELETE(_curve);
}

void StrokeCommandImpl::draw()
{
    if (_curve)
        _curve->draw(surface);
}

StrokeCommand::StrokeCommand()
{
    SH_I(StrokeCommand);
    d->init();
}

StrokeCommand::~StrokeCommand()
{
    SH_E(StrokeCommand);
    d->exit();
}

void StrokeCommand::event(const SsUiEvent* evt)
{
    SH_D(StrokeCommand);
    if (evt->type == S_BUTTON_DOWN)
    {
        if (evt->wbutton.button == S_BTN1_DN)
        {
            d->exit();
            SsPoint* pnt = new SsPoint();
            pnt->x = evt->wbutton.x;
            pnt->y = evt->wbutton.y;
            d->_curve = new Curve();
            d->_curve->append(pnt);
            d->draw();
        }
    }
    else if (evt->type == S_MOUSE_MOVE)
    {
        if ((evt->wmotion.state & S_MASK_LBUTTON) && d->_curve)
        {
            if (d->_ctrlPnt1 && d->_ctrlPnt2)
            {
                SsPoint* pnt = new SsPoint();
                pnt->x = evt->wmotion.x;
                pnt->y = evt->wmotion.y;
                d->_curve->append(d->_ctrlPnt1);
                d->_curve->append(d->_ctrlPnt2);
                d->_curve->append(pnt);
                d->_ctrlPnt1 = SH_NULL;
                d->_ctrlPnt2 = SH_NULL;
                d->draw();
            }
            else if (d->_ctrlPnt1)
            {
                assert(d->_ctrlPnt2 == SH_NULL);
                d->_ctrlPnt2 = new SsPoint();
                d->_ctrlPnt2->x = evt->wmotion.x;
                d->_ctrlPnt2->y = evt->wmotion.y;
            }
            else
            {
                assert(d->_ctrlPnt2 == SH_NULL);
                d->_ctrlPnt1 = new SsPoint();
                d->_ctrlPnt1->x = evt->wmotion.x;
                d->_ctrlPnt1->y = evt->wmotion.y;
            }
        }
    }
    else if (evt->type == S_BUTTON_UP)
    {
        if (OM)
        {
            OM->append(d->_curve);
            d->draw();
            d->_curve = SH_NULL;
        }
        d->exit();
    }
}

bool StrokeCommand::invoke()
{
    return true;
}

} // namespace ShCo
